package com.ztesoft.zsmart.zcm.monitor.utils;

import com.ztesoft.zsmart.core.log.ZSmartLogger;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 导出xml，备份工具类
 * 
 * @author chen33
 */
public final class BackupUtil {
    private static final ZSmartLogger _logger = ZSmartLogger.getLogger(BackupUtil.class);

    private BackupUtil() {

    }

    public static void backupFile(String path, String bakPath) {
        String sourcePath = FileHelper.canonicalizeUrl(path);

        bakPath = FileHelper.vaildFilePath(bakPath);
        File bakDir = new File(bakPath);
        if (!bakDir.exists()) {
            bakDir.mkdir();
        }

        String source = sourcePath;
        String dest = bakPath + "/agent.xml_bak";

        copyFile(source, dest);
    }

    public static void renameBakFileToHistoryFile(String bakPath) {
        bakPath = FileHelper.canonicalizeUrl(bakPath);
        bakPath = FileHelper.vaildFilePath(bakPath);
        File bakDir = new File(bakPath);
        if (!bakDir.exists()) {
            bakDir.mkdir();
        }

        String source = bakPath + "/agent.xml_bak";
        String dest = bakPath + "/agent.xml";

        source = FileHelper.canonicalizeUrl(source);
        source = FileHelper.vaildFilePath(source);
        File file = new File(source);
        if (file.exists()) {
            long lastModTime = file.lastModified();
            Date date = new Date(lastModTime);
            String formatStr = "yyyy-MM-dd_HH-mm-ss";
            SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
            String d = sdf.format(date);

            dest = dest + "_" + d;
            dest = FileHelper.canonicalizeUrl(dest);
            dest = FileHelper.vaildFilePath(dest);
            file.renameTo(new File(dest));
        }
    }

    public static void deleteBakFile(String bakPath) {
        bakPath = FileHelper.canonicalizeUrl(bakPath);
        bakPath = FileHelper.vaildFilePath(bakPath);
        File bakDir = new File(bakPath);
        if (!bakDir.exists()) {
            bakDir.mkdir();
        }

        String source = bakPath + "/agent.xml_bak";

        File file = new File(source);
        if (file.exists()) {
            if (file.delete()) {
                _logger.info("Succeed in deleting bak file [" + file.getName() + "].");
            }
            else {
                _logger.error("Fail to delete bak file [" + file.getName() + "].");
            }
        }
    }

    private static void copyFile(String srcFileName, String desFileName) {
        srcFileName = FileHelper.vaildFilePath(srcFileName);
        desFileName = FileHelper.vaildFilePath(desFileName);
        File srcFile = new File(FileHelper.canonicalizeUrl(srcFileName));
        File desFile = new File(FileHelper.canonicalizeUrl(desFileName));

        if (!srcFile.exists()) {
            _logger.info("Source file[" + srcFileName + "] to be copied does not exist.");
            return;
        }
        else {
            if (srcFile.isFile()) {
                if (!desFile.exists()) {

                    try (FileInputStream fileInputStream = new FileInputStream(srcFile);
                         BufferedInputStream inBuffer = new BufferedInputStream(fileInputStream);
                         FileOutputStream fileOutputStream = new FileOutputStream(desFile);
                         BufferedOutputStream outBuffer = new BufferedOutputStream(fileOutputStream)) {
                        byte[] b = new byte[1024 * 5];
                        int len;
                        while ((len = inBuffer.read(b)) != -1) {
                            outBuffer.write(b, 0, len);
                        }
                        outBuffer.flush();
                    }
                    catch (FileNotFoundException e1) {
                        _logger.error("File[" + srcFileName + "] does not exist.");
                        return;
                    }
                    catch (IOException e) {
                        _logger.error("Error when copy file from [" + srcFileName + "] to [" + desFileName
                                + "],error message:" + e.getMessage());
                        return;
                    }

                }
                else {
                    // _logger.info("Destination file[" + desFileName + "] exists.");
                    return;
                }
            }
            else {
                _logger.info("Only file can be copied.");
                return;
            }
        }
    }

    public static String parseCmd(String oldCmd) {
        String newCmd = null;

        Pattern pattern = Pattern.compile("\\$[\\w_\\-]+/");
        Matcher matcher = pattern.matcher(oldCmd);

        // int sep = -1;
        // sep = oldCmd.indexOf(' ');
        // String cmdHeart = oldCmd.substring(0, sep);
        // String param = oldCmd.substring(sep + 1);
        String param = oldCmd;
        boolean result = matcher.find();
        while (result) {
            for (int j = 0; j <= matcher.groupCount(); j++) {
                String tmp = matcher.group(j);
                String tmp1 = tmp.substring(1, tmp.length() - 1);
                String env = System.getenv(tmp1);
                if (env == null) {
                    // _logger.error("Please configure environment variable[" + tmp1 + "].");
                    return null;
                }
                param = param.replace(tmp, env + "/");
            }
            result = matcher.find();
        }

        // newCmd = custReplace(cmdHeart+" "+param);
        newCmd = custReplace(param);
        return newCmd;
    }

    private static String custReplace(String str) {
        int index = str.indexOf("\\");
        while (index != -1) {
            String q = str.substring(0, index);
            String h = str.substring(index + 1);
            str = q + "/" + h;
            index = str.indexOf("\\");
        }
        return str;
    }
}
